package com.mbengue.corp.artisan.dao.impl;

import java.sql.Timestamp;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.util.Assert;

import com.mbengue.corp.artisan.dao.FeuilleDao;
import com.mbengue.corp.artisan.modele.Client;
import com.mbengue.corp.artisan.modele.Devis;
import com.mbengue.corp.artisan.modele.Facture;
import com.mbengue.corp.artisan.modele.Feuille;

public class FeuilleDaoImpl implements FeuilleDao {
  private static Logger logger = Logger.getLogger(FeuilleDao.class);
  private HibernateTemplate hbTemplate;

  public void setSessionFactory(SessionFactory sessionFactory) {
    this.hbTemplate = new HibernateTemplate(sessionFactory);
  }

  @Override
  public void ajouterFeuille(Feuille feuille) throws DataAccessException {
    logger.info("Ajout d'une nouvelle feuille: " + feuille);
    this.hbTemplate.saveOrUpdate(feuille);
  }

  @Override
  public void modifierFeuille(Feuille feuille) throws DataAccessException {
    logger.info("Mise a jour de la feuille: " + feuille);
    this.hbTemplate.update(feuille);
  }

  @Override
  public void supprimerFeuille(Feuille feuille) throws DataAccessException {
    logger.info("Feuille a supprimer: " + feuille);
    this.hbTemplate.delete(feuille);
  }

  @Override
  public Feuille trouverFeuilleParNumero(String type, String numero) throws DataAccessException {
    logger.info("Trouve la feuille de type (" + type + ") dont le numero contient: " + numero);
    List<Feuille> feuilles = this.trouverFeuillesParNumero(type, numero);
    Assert.notNull(feuilles);
    Assert.isTrue(feuilles.size() <= 1);

    if (feuilles.size() == 0) {
      return null;
    }
    return feuilles.get(0);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Feuille> toutesLesFeuilles() throws DataAccessException {
    logger.info("Recupere toutes les factures et tous les devis");
    DetachedCriteria criteria = DetachedCriteria.forClass(Feuille.class);
    return this.hbTemplate.findByCriteria(criteria);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Devis> tousLesDevis() throws DataAccessException {
    logger.info("Recupere tous les devis");
    return this.hbTemplate.findByNamedQuery("tousLesDevis");
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Facture> toutesLesFactures() throws DataAccessException {
    logger.info("Recupere toutes les factures");
    return this.hbTemplate.findByNamedQuery("toutesLesFactures");
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Facture> trouverFacturesParDates(Timestamp debut, Timestamp fin) throws DataAccessException {
    logger.info("Trouve les factures creees entre " + debut + " et " + fin);
    return this.hbTemplate.findByNamedQuery("trouverFactureParDate", new Timestamp[] { debut, fin });
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Devis> trouverDevisParDates(Timestamp debut, Timestamp fin) throws DataAccessException {
    logger.info("Trouve les devis crees entre " + debut + " et " + fin);
    return this.hbTemplate.findByNamedQuery("trouverDevisParDate", new Timestamp[] { debut, fin });
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Facture> trouverFacturesParClient(Client client) throws DataAccessException {
    logger.info("Trouve les factures editees pour le client " + client);
    return this.hbTemplate.findByNamedQuery("trouverFactureParClient", client.getClientId());
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Devis> trouverDevisParClient(Client client) throws DataAccessException {
    logger.info("Trouve les devis edites pour le client " + client);
    return this.hbTemplate.findByNamedQuery("trouverDevisParClient", client.getClientId());
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Feuille> trouverFeuillesParClient(Client client) throws DataAccessException {
    logger.info("Trouve toutes les feuilles éditées pour: " + client);
    return this.hbTemplate.findByNamedQuery("toutesLesFeuillesD1Client", client.getClientId());
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Feuille> trouverFeuillesParNumero(String type, String numero) throws DataAccessException {
    logger.info("Trouve toutes les feuilles de type (" + type + ") dont le numero contient: " + numero);
    return this.hbTemplate.findByNamedQuery("trouverFeuilleParNumero", new String[] { type, "%" + numero + "%" });
  }

  @SuppressWarnings("unchecked")
  @Override
  public void supprimerFeuilleParClient(Client client) throws DataAccessException {
    logger.info("Suppression des feuilles etablies pour le client: " + client);
    List<Feuille> feuilles = this.hbTemplate.find("select f from feuille f where f.client = ?", client);
    this.hbTemplate.deleteAll(feuilles);
  }
}
